package com.hqd.ch03.v39.web.method.annotation;

import com.hqd.ch03.utils.PatternMatchUtils;
import com.hqd.ch03.v39.core.MethodParameter;
import com.hqd.ch03.v39.web.context.request.NativeWebRequest;
import com.hqd.ch03.v39.web.method.support.HandlerMethodReturnValueHandler;
import com.hqd.ch03.v39.web.servlet.ModelAndView;
import com.hqd.ch03.v39.web.servlet.SmartView;
import com.hqd.ch03.v39.web.servlet.View;
import com.hqd.ch03.v39.web.servlet.support.ModelAndViewContainer;

public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturnValueHandler {


    private String[] redirectPatterns;

    public String[] getRedirectPatterns() {
        return this.redirectPatterns;
    }

    public void setRedirectPatterns(String... redirectPatterns) {
        this.redirectPatterns = redirectPatterns;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return ModelAndView.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

        if (returnValue == null) {
            mavContainer.setRequestHandled(true);
            return;
        }

        ModelAndView mav = (ModelAndView) returnValue;
        if (mav.isReference()) {
            String viewName = mav.getViewName();
            mavContainer.setViewName(viewName);
            if (viewName != null && isRedirectViewName(viewName)) {
                mavContainer.setRedirectModelScenario(true);
            }
        } else {
            View view = mav.getView();
            mavContainer.setView(view);
            if (view instanceof SmartView && ((SmartView) view).isRedirectView()) {
                mavContainer.setRedirectModelScenario(true);
            }
        }
        mavContainer.setStatus(mav.getStatus());
        mavContainer.addAllAttributes(mav.getModel());
    }

    protected boolean isRedirectViewName(String viewName) {
        return (PatternMatchUtils.simpleMatch(this.redirectPatterns, viewName) || viewName.startsWith("redirect:"));
    }

}